﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Newtonsoft.Json.Linq;
using System.IO;
using Newtonsoft.Json;

namespace BasePlatformCommon
{
	[JsonObject(MemberSerialization.OptIn)]
	public class SubControl : Device
	{
		public bool HasErrorNeedDisp { get; set; }				// 存在需在界面显示的错误（标红）

		public bool HasNoContinueMarkNeedDisp { get; set; }		// 存在需在界面显示的错误（编号不连续, 标记 "*" ）

		public int brotherCount = 0;							// 等位分控数量

		[JsonProperty]
		public PInfoData ProductionInfo { get; set; }	// 产品信息

		[JsonProperty]
		public int BelongMainPort { get; set; }			// 分控所属的主控端口

		[JsonProperty]
		public int DeviceSerNum { get; set; }			// 设备序号

		[JsonProperty]
		public int CommState { get; set; }				// 分控通信状态 0-通讯正常, 1-通讯异常

		[JsonProperty]
		public int TotalComm { get; set; }				// 总包数

		[JsonProperty]
		public int ErrorComm { get; set; }				// 错误包数

		[JsonProperty]
		public int DeclareSubPortNum { get; set; }		// 声明的分控端口数

		[JsonProperty]
		public int TotalSubPortNum { get; set; }		// 总分控端口数

		[JsonProperty]
		public int DeclareLampNum { get; set; }			// 声明的灯点数

		[JsonProperty]
		public int TotalLampNum { get; set; }			// 总灯点数

		[JsonProperty]
		public int ErrorLampNum { get; set; }			// 异常灯点数

		public List<SubPort> SubPortList { get; set; }	// 分控端口数据集合

        public bool ReachMaxPacketNum { get; set; }		// 总包数或错包数达到最大

        [JsonProperty]
        public SubFaultDetail FaultDetail { get; set; }			// 异常详情
		
		/*******************************************************************/
        public int[] portLampNum { get; set; }			// 总灯点数

		private byte[] replyDataBytes = new byte[256];	// 状态反馈数据 256byte

		private double normalPercent = 0.3;				// 正常比例范围
		
		private double errorPercent = 0.7;				// 异常比例范围

		// 无参构造函数
		public SubControl()
		{
			deviceType = DeviceType.SubControl;

			this.name = "分控";
			if (LanguageOper.available == true)
			{
				this.name = LanguageOper.ReadValue("Chain", "sub.name");
			}

			ProductionInfo = new PInfoData();
			BelongMainPort = 0;
			DeviceSerNum = 0;
			CommState = 0;
			TotalComm = 0;
			ErrorComm = 0;
			DeclareSubPortNum = -1;
			TotalSubPortNum = 0;
			DeclareLampNum = -1;
			SubPortList = new List<SubPort>();
            portLampNum = new int[16];

			TotalLampNum = 0;
			ErrorLampNum = 0;
            for (int i = 0; i < 16; i++)
            {
                portLampNum[i] = 0;
                TotalLampNum = TotalLampNum + portLampNum[i];
            }

		}

        // 构造函数
        public SubControl(byte[] replyBytes)
            : this() {
            if (replyBytes != null) {
                var len = replyBytes.Length;
                replyDataBytes = new byte[len];
                Array.Copy(replyBytes, 0, replyDataBytes, 0, len);
                parseReplyDataBytes();
            }
        }

		// 解析分控状态反馈数据 - 256 byte
		private void parseReplyDataBytes()
		{
			// 错误包数
			ErrorComm = replyDataBytes[0] | replyDataBytes[1] << 8;

			// 总包数
			TotalComm = replyDataBytes[2] | replyDataBytes[3] << 8 | replyDataBytes[4] << 16 | replyDataBytes[5] << 24;

            //if (replyDataBytes.Length > 64) {
                // 添加端口 Port1-Port8, 并解析总点数与错误点数
                SubPort port1 = new SubPort();
                port1.index = 0;
                port1.TotalLampNum = replyDataBytes[0x80] | replyDataBytes[0x81] << 8;	// Port1 总点数
                port1.ErrorLampNum = replyDataBytes[0x82] | replyDataBytes[0x83] << 8;	// Port1 错误点数
                SubPort port2 = new SubPort();
                port2.index = 1;
                port2.TotalLampNum = replyDataBytes[0x84] | replyDataBytes[0x85] << 8;	// Port2 总点数
                port2.ErrorLampNum = replyDataBytes[0x86] | replyDataBytes[0x87] << 8;	// Port2 错误点数
                SubPort port3 = new SubPort();
                port3.index = 2;
                port3.TotalLampNum = replyDataBytes[0x88] | replyDataBytes[0x89] << 8;	// Port3 总点数
                port3.ErrorLampNum = replyDataBytes[0x8a] | replyDataBytes[0x8b] << 8;	// Port3 错误点数
                SubPort port4 = new SubPort();
                port4.index = 3;
                port4.TotalLampNum = replyDataBytes[0x8c] | replyDataBytes[0x8d] << 8;	// Port4 总点数
                port4.ErrorLampNum = replyDataBytes[0x8e] | replyDataBytes[0x8f] << 8;	// Port4 错误点数
                SubPort port5 = new SubPort();
                port5.index = 4;
                port5.TotalLampNum = replyDataBytes[0x90] | replyDataBytes[0x91] << 8;	// Port5 总点数
                port5.ErrorLampNum = replyDataBytes[0x92] | replyDataBytes[0x93] << 8;	// Port5 错误点数
                SubPort port6 = new SubPort();
                port6.index = 5;
                port6.TotalLampNum = replyDataBytes[0x94] | replyDataBytes[0x95] << 8;	// Port6 总点数
                port6.ErrorLampNum = replyDataBytes[0x96] | replyDataBytes[0x97] << 8;	// Port6 错误点数
                SubPort port7 = new SubPort();
                port7.index = 6;
                port7.TotalLampNum = replyDataBytes[0x98] | replyDataBytes[0x99] << 8;	// Port7 总点数
                port7.ErrorLampNum = replyDataBytes[0x9a] | replyDataBytes[0x9b] << 8;	// Port7 错误点数
                SubPort port8 = new SubPort();
                port8.index = 7;
                port8.TotalLampNum = replyDataBytes[0x9c] | replyDataBytes[0x9d] << 8;	// Port8 总点数
                port8.ErrorLampNum = replyDataBytes[0x9e] | replyDataBytes[0x9f] << 8;	// Port8 错误点数

                SubPortList.Clear();

                SubPortList.Add(port1);
                SubPortList.Add(port2);
                SubPortList.Add(port3);
                SubPortList.Add(port4);
                SubPortList.Add(port5);
                SubPortList.Add(port6);
                SubPortList.Add(port7);
                SubPortList.Add(port8);

                // 分控端口数
                TotalSubPortNum = SubPortList.Count;

                // 分控总灯点数
                TotalLampNum = port1.TotalLampNum + port2.TotalLampNum + port3.TotalLampNum + port4.TotalLampNum
                                + port5.TotalLampNum + port6.TotalLampNum + port7.TotalLampNum + port8.TotalLampNum;

                // 分控异常灯点数
                ErrorLampNum = port1.ErrorLampNum + port2.ErrorLampNum + port3.ErrorLampNum + port4.ErrorLampNum
                                + port5.ErrorLampNum + port6.ErrorLampNum + port7.ErrorLampNum + port8.ErrorLampNum;
            //}
            

			double factor = 0.0;
			if (TotalLampNum > 0)
			{
				factor = ((double)ErrorComm) / ((double)TotalComm);
			}

			if (factor <= 0.3)
			{
				CommState = 0;		// 通信正常
			}
			else if (factor > 0.3 && factor < 0.7)
			{
				CommState = 1;		// 通信不良
			}
			else
			{
				CommState = 2;		// 通信异常
			}

			// 判断总包数、错包数是否达到最大
			if (TotalComm >= 2147483648 - 100 || ErrorComm >= 32768 - 100)
			{
				ReachMaxPacketNum = true;
			}
			else
			{
				ReachMaxPacketNum = false;
			}

            if (CommState != 0) 
            {
                FaultDetail = new SubFaultDetail();

                FaultDetail.SubNum = DeviceSerNum;

                FaultDetail.SubPort = BelongMainPort;

                FaultDetail.FaultType = buildTipMessage();

                FaultDetail.FaultTime = DateTime.Now.ToString();
            }
		}

		// 拼接提示信息
		public string buildTipMessage()
		{
			string tip1 = "通信正常";
			string tip2 = "通信异常";
			string tip3 = "通信不良";
            string formatStr = ", 灯具 {0} / {1}, 通信包 {2} / {3}";

			if (LanguageOper.available == true)
			{
				tip1 = LanguageOper.ReadValue("Chain", "sub.commNormal");
				tip2 = LanguageOper.ReadValue("Chain", "sub.commError");
				tip3 = LanguageOper.ReadValue("Chain", "sub.commBad");
                //formatStr = LanguageOper.ReadValue("Chain", "sub.formatStr");
			}

			StringBuilder sb = new StringBuilder();

			double ruler = TotalComm == 0 ? 0.0 : ErrorComm * 1.0 / TotalComm;
			if (ruler <= normalPercent)
			{
				sb.Append(tip1);
			}
			else if (ruler > errorPercent)
			{
				sb.Append(tip2);
			}
			else
			{
				sb.Append(tip3);
			}

            sb.Append(String.Format(formatStr, TotalLampNum, ErrorLampNum, TotalComm, ErrorComm));

			tipMessage = sb.ToString();
			return tipMessage;
		}

		#region Json交互相关操作

		// 设置分控数据
		public void setSubControlData(JObject jsonData)
		{
			parseSubPortListData(jsonData);
			
			parseSubControlState();
		}

		// 解析分控端口集合数据
		private void parseSubPortListData(JObject jsonData)
		{
			try
			{
				// 通用属性
				ProductionInfo.Manufacturer = (string)jsonData["Manufacturer"];
				ProductionInfo.ProductionDate = (string)jsonData["ProductionDate"];
				ProductionInfo.ProductionType = (string)jsonData["ProductionType"];
				ProductionInfo.SerialNumber = (string)jsonData["SerialNumber"];
				ProductionInfo.Version = (string)jsonData["Version"];

				// 独立属性
				BelongMainPort = (int)jsonData["BelongMainPort"];
				DeviceSerNum = (int)jsonData["DeviceSerNum"];
				CommState = (int)jsonData["CommState"];
				TotalComm = (int)jsonData["TotalComm"];
				ErrorComm = (int)jsonData["ErrorComm"];
				DeclareSubPortNum = (int)jsonData["DeclareSubPortNum"];
				TotalSubPortNum = (int)jsonData["TotalSubPortNum"];

				for (int portIndex = 0; portIndex < TotalSubPortNum; portIndex++)
				{
					string portNameStr = "SubPort" + portIndex.ToString();
					parseSubPortData((JObject)jsonData[portNameStr]);
				}
			}
			catch
			{
				Log.DebugLogger.Error("SubPortList Parse Error!");
			}
		}

		// 解析分控端口数据
		private void parseSubPortData(JObject jsonData)
		{
			SubPort subPort = new SubPort();
			subPort.setSubPortData(jsonData);
			SubPortList.Add(subPort);
		}

		// 解析分控状态 - 通讯异常灯点数
		private void parseSubControlState()
		{
			ErrorLampNum = 0;
			for (int indexport = 0; indexport < TotalSubPortNum; indexport++)
			{
				ErrorLampNum += SubPortList[indexport].ErrorLampNum;
				TotalLampNum += SubPortList[indexport].TotalLampNum;
			}
		}

		#endregion
	}

    public class SubFaultDetail : JsonClassBase<SubFaultDetail> 
    {
        public int SubNum = 0;

        public int SubPort = 0;

        public string FaultType = "";

        public string FaultTime = "";
    }
}
